<template>
  <n-form ref="formRef" :model="researchInfo" :rules="rules">
    <n-form-item path="type" label="类型">
      <n-select v-model:value="researchInfo.type" :options="TYPE_OPTIONS" />
    </n-form-item>
    <n-form-item path="title" label="标题">
      <n-input v-model:value="researchInfo.title" @keydown.enter.prevent />
    </n-form-item>
    <n-form-item label="作者">
      <n-select
        v-model:value="tmpAuthors"
        multiple
        :options="authorOptions"
        :render-label="renderLabel"
        :render-tag="renderSelectTag"
        filterable
        tag
        :on-create="hangleCreateOption"
      />
    </n-form-item>
    <n-form-item path="file" label="附件">
      <n-upload
        :max="1"
        @before-upload="beforeUpload"
        :custom-request="uploadFile"
        directory-dnd
      >
        <n-upload-dragger>
          <div class="mb-3">
            <n-icon size="48" :depth="3">
              <archive-icon />
            </n-icon>
          </div>
          <n-text style="font-size: 16px">
            点击或者拖动文件到该区域来上传
          </n-text>
        </n-upload-dragger>
      </n-upload>
    </n-form-item>
    <n-form-item path="abstract" label="简介">
      <n-input
        v-model:value="researchInfo.abstract"
        maxlength="300"
        show-count
        type="textarea"
        :autosize="{
          minRows: 3
        }"
        @keydown.enter.prevent
      />
    </n-form-item>
    <div class="flex justify-between">
      <n-form-item label="年" class="w-1/3">
        <n-select
          v-model:value="researchInfo.date.year"
          :options="YEAR_OPTIONS"
        />
      </n-form-item>
      <n-form-item label="月" class="w-1/3">
        <n-select
          v-model:value="researchInfo.date.month"
          :options="MONTH_OPTIONS"
        />
      </n-form-item>
      <n-form-item label="日" class="w-1/3">
        <n-select
          v-model:value="researchInfo.date.day"
          :options="DAY_OPTIONS"
        />
      </n-form-item>
    </div>
    <n-form-item label="期刊名" v-show="researchInfo.type === 'JOUR'">
      <n-input
        v-model:value="researchInfo.other.journalName"
        @keydown.enter.prevent
      />
    </n-form-item>
    <div class="flex justify-between" v-show="researchInfo.type === 'JOUR'">
      <n-form-item label="期" class="w-1/3">
        <n-input
          v-model:value="researchInfo.other.volume"
          @keydown.enter.prevent
        />
      </n-form-item>
      <n-form-item label="卷" class="w-1/3">
        <n-input
          v-model:value="researchInfo.other.issue"
          @keydown.enter.prevent
        />
      </n-form-item>
      <n-form-item label="页" class="w-1/3">
        <n-input
          v-model:value="researchInfo.other.page"
          @keydown.enter.prevent
        />
      </n-form-item>
    </div>
    <n-form-item label="会议" v-show="researchInfo.type === 'CPAPER'">
      <n-input
        v-model:value="researchInfo.other.conferenceTitle"
        @keydown.enter.prevent
      />
    </n-form-item>
    <n-form-item label="地点" v-show="researchInfo.type === 'CPAPER'">
      <n-input
        v-model:value="researchInfo.other.location"
        @keydown.enter.prevent
      />
    </n-form-item>
    <div class="flex justify-end">
      <n-button type="primary" @click="submit">提交</n-button>
    </div>
  </n-form>
</template>

<script setup>
import { ArchiveOutline as ArchiveIcon } from '@vicons/ionicons5'
import api from '@/api/api'
import { NAvatar, NText, NTag } from 'naive-ui'

const props = defineProps(['researchInfo'])
const emit = defineEmits()

const message = useMessage()

const formRef = ref(null)

const rules = {
  type: [
    {
      required: true,
      trigger: ['input', 'blur']
    }
  ],
  title: [
    {
      required: true,
      validator(rule, value) {
        if (!value) {
          return new Error('请输入标题')
        } else if (value.length > 300) {
          return new Error('标题长度应小于300字符')
        }
        return true
      },
      trigger: ['input', 'blur']
    }
  ],
  abstract: [
    {
      required: true,
      validator(rule, value) {
        if (!value) {
          return new Error('请输入简介')
        } else if (value.length > 300) {
          return new Error('简介长度应小于300字符')
        }
        return true
      },
      trigger: ['input', 'blur']
    }
  ]
}

const TYPE_OPTIONS = [
  {
    label: '期刊论文',
    value: 'JOUR'
  },
  {
    label: '会议论文',
    value: 'CPAPER'
  },
  {
    label: '数据',
    value: 'DATA'
  }
]

const YEAR_OPTIONS = Array.from({ length: 75 }, (ele, index) => {
  const res = `${index + 1949}`
  return { label: res, value: res }
}).reverse()

const MONTH_OPTIONS = Array.from({ length: 13 }, (ele, index) => {
  if (index === 0) {
    return { label: '(可选)', value: '' }
  } else {
    const res = `${index}`
    return { label: res, value: res }
  }
})

const DAY_OPTIONS = Array.from({ length: 32 }, (ele, index) => {
  if (index === 0) {
    return { label: '(可选)', value: '' }
  } else {
    const res = `${index}`
    return { label: res, value: res }
  }
})

watch(
  () => props.researchInfo.type,
  () => {
    props.researchInfo.other = {
      journalName: '',
      volume: '',
      issue: '',
      page: '',
      conferenceTitle: '',
      location: ''
    }
  }
)

// 文件上传前检测
const beforeUpload = (data) => {
  if (data.file.file?.size > 10000000) {
    message.warning('请确保文件小于10MB')
    return false
  }
  return true
}

// 上传请求
const uploadFile = ({ file }) => {
  const formData = new FormData()
  formData.append('file', file.file)
  api.Common.uploadFile(formData)
    .then((res) => {
      if (res.success) {
        props.researchInfo.file.url = res.url
        props.researchInfo.file.fid = res.fid
      } else {
        message.error('文件上传失败，请重试')
      }
    })
    .catch(() => {
      message.error('文件上传失败，请重试')
    })
}

// 提交
const submit = () => {
  // 日期合法性检验
  if (!props.researchInfo.date.year) {
    message.warning('至少需要提供年份')
    return false
  }
  if (props.researchInfo.date.day && !props.researchInfo.date.month) {
    message.warning('请检查日期是否合法')
    return false
  }
  const date = `${props.researchInfo.date.year}-${
    props.researchInfo.date.month
      ? props.researchInfo.date.month.padStart(2, '0')
      : '01'
  }-${
    props.researchInfo.date.day
      ? props.researchInfo.date.day.padStart(2, '0')
      : '01'
  }`
  const dateCheck = (date) => {
    return new Date(date).getDate() == date.substring(date.length - 2)
  }
  if (!dateCheck(date)) {
    message.warning('请检查日期是否合法')
    return false
  }

  if (tmpAuthors.value.length === 0) {
    message.warning('请确保至少有一名作者')
    return false
  }

  formRef.value?.validate((error) => {
    if (!error) {
      props.researchInfo.authors = tmpAuthors.value
      emit('submit')
    } else {
      message.warning('请检查信息是否符合规则')
    }
  })
}

onMounted(() => {
  init()
})

const init = () => {
  api.User.searchInInstitution().then((res) => {
    authorOptions.value = res.data.users.map((item) => {
      return {
        label: item.name,
        value: {
          isUser: true,
          ...item
        }
      }
    })
  })
}

const authorOptions = ref([])

// 动态创建选项
const hangleCreateOption = (label) => {
  return {
    label,
    value: {
      isUser: false,
      name: label
    }
  }
}

// 作者临时存储
const tmpAuthors = ref([])
watch(
  () => props.researchInfo.authors,
  () => {
    if (
      props.researchInfo.authors.length > 0 &&
      typeof props.researchInfo.authors[0] === 'string'
    ) {
      tmpAuthors.value = props.researchInfo.authors.map((item) => {
        return {
          isUser: false,
          name: item
        }
      })
    }
  }
)

const renderLabel = (option) => {
  return h(
    'div',
    {
      style: {
        display: 'flex',
        alignItems: 'center'
      }
    },
    [
      option.value.isUser &&
        h(NAvatar, {
          src: option.value.avatar,
          round: true,
          size: 'small'
        }),
      h(
        'div',
        {
          style: {
            marginLeft: '12px',
            padding: '4px 0'
          }
        },
        [
          h('div', null, [option.value.name]),
          h(
            NText,
            { depth: 3, tag: 'div' },
            {
              default: () => option.value.institution
            }
          )
        ]
      )
    ]
  )
}

const renderSelectTag = ({ option, handleClose }) => {
  return h(
    NTag,
    {
      style: {
        padding: '0 6px 0 4px'
      },
      round: true,
      closable: true,
      onClose: (e) => {
        e.stopPropagation()
        handleClose()
      }
    },
    {
      default: () =>
        h(
          'div',
          {
            style: {
              display: 'flex',
              alignItems: 'center'
            }
          },
          [
            option.value.isUser &&
              h(NAvatar, {
                src: option.value.avatar,
                round: true,
                size: 22,
                style: {
                  marginRight: '4px'
                }
              }),
            option.value.name
          ]
        )
    }
  )
}
</script>

<style scoped></style>
